package com.ruoyi.common.utils.kiam;

import com.google.gson.Gson;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * 接口签名演示类
 */
public class SignatureDemo {
    // 接口服务地址
    static String restSever = "http://1.85.55.225:8888/kiam/urm/service/V3/res/orgs";
    // 身份系统提供给应用对接的应用标识
    static String appKey = "0528918565740544";
    // 身份系统签发给应用对接的密钥
    static String pwd = "d6e5eaeb74939a3d633bb6c136d3ad8c885da4e5";

    public static void main(String[] args) {
        // 时间戳
        Long ts = Calendar.getInstance().getTime().getTime();
        // 随机数
        String once = RandomStringUtils.randomAlphanumeric(32);
        String signMethod = "SHA-256";
        // 接口header中的公共参数
        String commonParamUrl = String.format("appKey=%s" + "&" + "ts=%s" + "&" + "once=%s" + "&" + "signMethod=%s", appKey, ts, once, signMethod);

        // 创建HttpClient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        /**
         * GET查询接口演示代码
         */
        String getQueryParam = "startTime=1570589279000";
        String getFullUrl = restSever + "?" + getQueryParam;
        HttpGet httpGet = new HttpGet(getFullUrl);
        // get请求查询参数，用在URL上的，这里若是通过ID查询的，接口中ID是作为路径存在的，所以需要将ID组合成
        String getAllParamUrl = commonParamUrl + "&" + getQueryParam;
        // 对参数签名，并放入请求header中的signData参数中
        try {
            // 签名数据
            String signData = TokenUtil.getSignature(pwd, getAllParamUrl, signMethod);
            // 添加header参数 appCode、timestamp、 signatureonce、signature
            httpGet.addHeader("appKey", appKey);
            httpGet.addHeader("ts", ts.toString());
            httpGet.addHeader("once", once);
            httpGet.addHeader("signMethod", signMethod);
            httpGet.addHeader("signData", signData);
            System.out.println("appKey:" + appKey);
            System.out.println("ts:" + ts.toString());
            System.out.println("once:" + once);
            System.out.println("signData:" + signData);
//            System.out.println("headers:" + httpGet.getAllHeaders());

            String urlStr = httpGet.getURI().toString();

            // 公共参数URL
            System.out.println("commonParamter:" + urlStr);

            if (StringUtils.endsWith(urlStr, "/")) {
                urlStr = StringUtils.removeEnd(urlStr, "/");
            }

            httpGet.setURI(new URI(urlStr));
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000)
                    .setConnectionRequestTimeout(3000).setSocketTimeout(3000).build();
            httpGet.setConfig(requestConfig);
            System.out.println("urlStr in request:" + httpGet.getURI().toString());

            // 执行请求
            CloseableHttpResponse response = httpclient.execute(httpGet);
            // 取响应的结果
            int statusCode = response.getStatusLine().getStatusCode();
            // 打印响应结果
            if (statusCode == HttpStatus.SC_OK) {
                String resp = EntityUtils.toString(response.getEntity(), "utf-8");
                System.out.println("status:" + statusCode);
                System.out.println("result:" + resp);
            }
        } catch (URISyntaxException e) {
            //签名失败
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e){
            e.printStackTrace();
        }

        /**
         * PUT修改接口的演示代码，POST与PUT类似
         */
        String ID = "aa03a5c692cf480b87887e0ff8cfe566";
        // 这里若是通过ID查询的，接口中ID是作为路径存在的，所以需要将ID组合成
        String putQueryParam = "ID=" + ID;
        String putFullUrl = restSever + "/" + ID; // 访问用户接口
        HttpPut httpPut = new HttpPut(putFullUrl);
        // 模拟POST/PUT的body中数据，需转为JSON进行签名。GET则没有这部分内容。
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("USER_NAME", "张三");
        String bodyParam = new Gson().toJson(dataMap);
        String postAllParamUrl = commonParamUrl + "&" + putQueryParam + "&bodyData=" + bodyParam;

        StringEntity bodyData = new StringEntity(bodyParam.toString(), "UTF-8");
        httpPut.setEntity(bodyData);
        // 对参数签名，并放入请求header中的signData参数中
        try {
            // 签名数据
            String signData = TokenUtil.getSignature(pwd, postAllParamUrl, signMethod);
            // 添加header参数 appCode、timestamp、 signatureonce、signature
            httpPut.addHeader("appKey", appKey);
            httpPut.addHeader("ts", ts.toString());
            httpPut.addHeader("once", once);
            System.out.println("once:" + once);

            httpPut.addHeader("signData", signData);

//            System.out.println("headers:" + httpPut.getAllHeaders());

            String urlStr = httpPut.getURI().toString();

            // 公共参数URL
            System.out.println("commonParamter:" + urlStr);

            if (StringUtils.endsWith(urlStr, "/")) {
                urlStr = StringUtils.removeEnd(urlStr, "/");
            }

            httpPut.setURI(new URI(urlStr));
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000)
                    .setConnectionRequestTimeout(3000).setSocketTimeout(3000).build();
            httpPut.setConfig(requestConfig);
            System.out.println("urlStr in request:" + httpPut.getURI().toString());

            // 执行请求
            CloseableHttpResponse response = httpclient.execute(httpPut);
            // 取响应的结果
            int statusCode = response.getStatusLine().getStatusCode();
            // 打印响应结果
            if (statusCode == HttpStatus.SC_OK) {
                String resp = EntityUtils.toString(response.getEntity(), "utf-8");
                System.out.println("status:" + statusCode);
                System.out.println("result:" + resp);
            }
        } catch (URISyntaxException e) {
            //签名失败
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}